﻿#include "Camera.h"
#include <sstream>
extern bool isStreaming;
extern bool m_bDevOpened;
AsynGrab::AsynGrab()
{
}
AsynGrab::~AsynGrab()
{   
	cvReleaseImage (&test);
    if(m_bDevOpened)
        CloseDevice();
    if ( NULL != m_pImage )
    {
        delete m_pImage;
        m_pImage = NULL;
    }
}
int AsynGrab::OpenDevice()
{
   GXInitLib();
   GX_STATUS      emStatus = GX_STATUS_SUCCESS;
   uint32_t       nDevNum  = 0;
   GX_OPEN_PARAM  stOpenParam;
   stOpenParam.accessMode = GX_ACCESS_EXCLUSIVE;
   stOpenParam.openMode   = GX_OPEN_INDEX;
   stOpenParam.pszContent = "1";

	// 枚举设备
	emStatus = GXUpdateDeviceList(&nDevNum, 1000);

	// 判断设备个数
	if (nDevNum <= 0)
	{
		return false ;
	}
	// 打开设备
	emStatus = GXOpenDevice(&stOpenParam, &m_hDevice);
	// 获取宽度
	emStatus = GXGetInt(m_hDevice, GX_INT_WIDTH, &m_nImageWidth);
	// 获取高度
	emStatus = GXGetInt(m_hDevice, GX_INT_HEIGHT, &m_nImageHeight);
	// 获取图像大小
	test = cvCreateImage(cvSize(m_nImageWidth, m_nImageHeight), 8, 3);
	emStatus = GXGetInt(m_hDevice, GX_INT_PAYLOAD_SIZE, &m_nPayLoadSize);
	//判断相机是否支持bayer格式
	emStatus = GXIsImplemented(m_hDevice, GX_ENUM_PIXEL_COLOR_FILTER, &m_bColorFilter);
	if (m_bColorFilter)
	{
		emStatus = GXGetEnum(m_hDevice, GX_ENUM_PIXEL_COLOR_FILTER, &m_nPixelColorFilter);
	}

	//为存储RGB图像数据申请空间
	m_pBufferRGB = new BYTE[(size_t)(m_nImageWidth * m_nImageHeight * 3)];
	if (m_pBufferRGB == NULL)
	{
		return false;
	}

	//为存储原始图像数据申请空间
	m_pBufferRaw = new BYTE[(size_t)m_nPayLoadSize];
	if (m_pBufferRaw == NULL)
	{
		delete []m_pBufferRGB;
		m_pBufferRGB = NULL;

		return false;
	}
	//初始化bitmap头
	m_pBmpInfo								= (BITMAPINFO *)m_chBmpBuf;
	m_pBmpInfo->bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
	m_pBmpInfo->bmiHeader.biWidth			= (LONG)m_nImageWidth;
	m_pBmpInfo->bmiHeader.biHeight			= (LONG)m_nImageHeight;
	m_pBmpInfo->bmiHeader.biPlanes			= 1;
	if (m_bColorFilter == true)
	{
		m_pBmpInfo->bmiHeader.biBitCount		= 24;

	}
	else
	{
		m_pBmpInfo->bmiHeader.biBitCount		= 8;
	}
	m_pBmpInfo->bmiHeader.biCompression		= BI_RGB;
	m_pBmpInfo->bmiHeader.biSizeImage		= 0;
	m_pBmpInfo->bmiHeader.biXPelsPerMeter	= 0;
	m_pBmpInfo->bmiHeader.biYPelsPerMeter	= 0;
	m_pBmpInfo->bmiHeader.biClrUsed			= 0;
	m_pBmpInfo->bmiHeader.biClrImportant	= 0;

	if (m_bColorFilter == true)
	{
	
	}else
	{
		// 黑白图像需要初始化调色板
		for(int i=0;i<256;i++)
		{
			m_pBmpInfo->bmiColors[i].rgbBlue	=i;
			m_pBmpInfo->bmiColors[i].rgbGreen	=i;
			m_pBmpInfo->bmiColors[i].rgbRed		=i;
			m_pBmpInfo->bmiColors[i].rgbReserved=i;
		}

	}

    m_bDevOpened = true;
	SetExposure(10000.0);
	//注册回调
	emStatus = GXRegisterCaptureCallback(m_hDevice, this, OnFrameCallbackFun);
   //设置自动白平衡
	emStatus=GXSetEnum(m_hDevice,GX_ENUM_BALANCE_WHITE_AUTO,GX_BALANCE_WHITE_AUTO_ONCE);
   //发开始采集命令
	emStatus = GXSendCommand(m_hDevice, GX_COMMAND_ACQUISITION_START);	
  return 1;
}

void __stdcall AsynGrab::OnFrameCallbackFun(GX_FRAME_CALLBACK_PARAM* pFrame)
 {
    AsynGrab *pWin = (AsynGrab*)(pFrame->pUserParam);
	if (pFrame->status == 0)
	{
		memcpy(pWin->m_pBufferRaw, pFrame->pImgBuf, pFrame->nImgSize);	
		// RGB转换
		if (pWin->m_bColorFilter)
		{
			DxRaw8toRGB24( pWin->m_pBufferRaw
				, pWin->m_pBufferRGB
				, (VxUint32)(pWin->m_nImageWidth)
				, (VxUint32)(pWin->m_nImageHeight)
				, RAW2RGB_NEIGHBOUR		         
				, DX_PIXEL_COLOR_FILTER(pWin->m_nPixelColorFilter)
				, false);
		}
		else
		{	// 黑白相机需要翻转数据后显示
			for(int i =0;i <pWin->m_nImageHeight;i++)
			{
				memcpy(pWin->m_pBufferRGB+i*pWin->m_nImageWidth, pWin->m_pBufferRaw+(pWin->m_nImageHeight-i-1)*pWin->m_nImageWidth,(size_t)pWin->m_nImageWidth);
			}

		}
		
		
		memcpy(pWin->test->imageData, pWin->m_pBufferRGB, (pWin->test->widthStep)*(pWin->test->height));
		//IplImage * src ;
		cvCvtColor(pWin->test,pWin->test,CV_BGR2RGB);

		//pWin->m_pImage =new QImage(pWin->m_pBufferRGB,pWin->m_nImageWidth,pWin->m_nImageHeight,QImage::Format_RGB888);
		//pWin->m_pImage =new QImage((uchar*)dstValue,pWin->m_nImageWidth,pWin->m_nImageHeight,QImage::Format_RGB888);
		pWin->m_pImage =new CImage((uchar*)(pWin->test)->imageData,pWin->m_nImageWidth,pWin->m_nImageHeight,CImage::Format_RGB888);
	//	cvReleaseImage(&test);
		// m_pImage->byteCount();
		if ( pWin->m_pImage != NULL)
		{	
		 pWin->onImageReceive(pWin->m_pImage);
			
		} 

		
     }

 }

 int AsynGrab::init()
 {

     m_bDevOpened = false;
     m_hDevice = NULL;
     m_pImage = NULL;
     bColorFliter = false;
	 isStreaming = false;
     return 1;
 }
 int AsynGrab::CloseDevice()      //关闭设备
 {
     // TODO: Add your control notification handler code here
	 m_bDevOpened = false;
	 
     GX_STATUS emStatus = GX_STATUS_ERROR;
     //发送停止采集命令
     emStatus = GXSendCommand(m_hDevice, GX_COMMAND_ACQUISITION_STOP);
     //注销回调
     emStatus = GXUnregisterCaptureCallback(m_hDevice);

     if (m_pBufferRGB != NULL)
      {
        delete[]m_pBufferRGB;
        m_pBufferRGB = NULL;
      }
     if (m_pBufferRaw != NULL)
      {
        delete[]m_pBufferRaw;
        m_pBufferRaw = NULL;
       }
    

	 //关闭相机
	
     emStatus = GXCloseDevice(m_hDevice);
     emStatus = GXCloseLib();

	 isStreaming = false;
     m_hDevice    = NULL;
     
     delete m_pImage;
     m_pImage = NULL;
     return 1;
	
 }
 //---------------------------------------------------------------------------------
 //brief  弹出错误信息
 //param  emErrorStatus  [in] 错误码
 //return 无
 //----------------------------------------------------------------------------------

 void AsynGrab::onStart()
 {
     if(!m_bDevOpened)
     {
         OpenDevice();
        // m_bDevOpened = true;
		 //isStreaming = true;
     }
     
 }
 void AsynGrab::onStop()
 {
	 if(m_bDevOpened)
     {
         CloseDevice();
        // m_bDevOpened = true;
		 //isStreaming = true;
     }
   
 }
 int AsynGrab::shutDown()
 {
     if(m_bDevOpened)
         CloseDevice();
    // m_pApiController->ShutDown();
     return 1;
 }

 GX_STATUS AsynGrab::SetExposure(double m_dShutterValue)
{
	GX_STATUS emStatus = GX_STATUS_SUCCESS;
	//设置曝光的形式
	emStatus = GXSetEnum(m_hDevice, GX_ENUM_EXPOSURE_AUTO, GX_EXPOSURE_AUTO_OFF );	
	//设置控制曝光的形式、曝光时间寄存器控制曝光时间
	emStatus = GXSetEnum(m_hDevice, GX_ENUM_EXPOSURE_MODE, GX_EXPOSURE_MODE_TIMED);
	//double m_dShutterValue;

	emStatus = GXSetFloat(m_hDevice, GX_FLOAT_EXPOSURE_TIME, m_dShutterValue);
	return (emStatus);
}
